"""
Copyright 2012 Wieser Dietmar, Margit Mutschlechner.

This file is part of Multimedia Social Networking Platform.

Multimedia Social Networking Platform is free software: 
you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Multimedia Social Networking Platform is distributed
in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Multimedia Social Networking Platform.  
If not, see <http://www.gnu.org/licenses/>.

"""

import traceback
from mutagen.easyid3 import EasyID3
from mutagen.mp3 import MP3
from msnp.logger import Logger
from mutagen import id3
from mutagen.asf import ASF
from msnp.persistence import XMLController

"""Module for writing and reading tags of media files. Currently it operates only with mp3, asf, wma and wmv files."""

ID3_TITLE = "title"
ID3_DATE = "date"
ID3_COMPOSER = "composer"
ID3_TRACKNUMBER = "tracknumber"
ID3_ALBUM = "album"
ID3_LENGTH = "length"
ID3_GENRE = "genre"
ID3_DISCNUMBER = "discnumber"
ID3_ARTIST = "artist"
ID3_BPM = "bpm"

ASF_TITLE = 'Title'
ASF_COMPOSER = 'WM/Composer'
ASF_TRACKNUMBER = 'WM/TrackNumber'
ASF_ALBUM = 'WM/AlbumTitle'
ASF_LENGTH = 'WM/Length'
ASF_GENRE = 'WM/Genre'
ASF_ARTIST = 'WM/AlbumArtist'
ASF_YEAR = 'WM/Year'
ASF_COLLECTION = 'WM/WMCollectionID'
ASF_LYRICS = 'WM/Lyrics'


__id3Filetypes = ["mp3"]
__asfFiletypes = ["asf", "wma", "wmv"]

def writeTags(url, audio):
    """Writes the tags of the given audio to the file at the given url.
    
    Depending on the type of the audio file it calls the __writeID3Tags
    or the __writeASFTags function.
    
    Args:
        url: The url of the audio file.
        audio: An Audio object representing the audio file.
    """
    
    global __id3Filetypes
    global __asfFiletypes
    
    filetype = url[len(url) - 3:]
    
    if __id3Filetypes.__contains__(filetype):
        __writeID3Tags(url, audio)
    elif __asfFiletypes.__contains__(filetype):
        __writeASFTags(url, audio)
    else:
        print "Filetype not recognized: " + filetype

def printTags(url):
    """Prints the tags of the given audio to the file.
    
    Depending on the type of audio file it calls the __printID3Tags or
    the __printASFTags function.
    
    Args:
        url: The url of the audio file.
    """
    global __id3Filetypes
    global __asfFiletypes
    
    filetype = url[len(url) - 3:]
    
    if __id3Filetypes.__contains__(filetype):
        __printID3Tags(url)
    elif __asfFiletypes.__contains__(filetype):
        __printASFTags(url)
    else:
        print "Filetype not recognized: " + filetype


def __writeID3Tags(url, audio):
    """Writes the ID3 tags of the given audio to the file at the given url.
    
    Args:
        url: The url of the audio file.
        audio: An Audio object representing the audio file.
    """
    Logger.info("changing MP3 tags for audio '" + audio.getMedia().getTitle() + "'")
    __writeEasyID3(url, audio)
    __writeID3(url, audio)
        
def __writeEasyID3(url, audio):
    """Writes the Easy ID3 tags, like title and year, of the given audio to the file at the given url.
    
    Args:
        url: The url of the audio file.
        audio: An Audio object representing the audio file.
    """
    try:
        Logger.info(" -> writeEasyID3 for audio ")
        id3Audio = EasyID3(url)
        #collect information
        title = audio.getMedia().getTitle()
        year = audio.getMedia().getYear()
        composer = audio.getMedia().getComposer()
        tracknumber = audio.getTracknumber()
        album = None
        if audio.getMedia().getCollection() != None:
            album = audio.getMedia().getCollection().getName()
        length = audio.getMedia().getLength()
        genre = None
        if audio.getMedia().getGenre() != None:
            genre = audio.getMedia().getGenre().getName()
        discnumber = audio.getDiscnumber()
        artist = audio.getArtist().getName()
        bpm = audio.getBPM()
        
        #write information to file
        if title != None and len(title) > 0:
            id3Audio[ID3_TITLE] = title
        if year != None and len(year) > 0:
            id3Audio[ID3_DATE] = year
        if composer != None and len(composer) > 0:
            id3Audio[ID3_COMPOSER] = composer
        if tracknumber != None and tracknumber > 0:
            id3Audio[ID3_TRACKNUMBER] = str(tracknumber)
        if album != None and len(album) > 0:
            id3Audio[ID3_ALBUM] = album
        if length != None and length > 0:
            id3Audio[ID3_LENGTH] = str(length)
        if genre != None and len(genre) > 0:
            id3Audio[ID3_GENRE] = genre
        if discnumber != None and discnumber > 0:
            id3Audio[ID3_DISCNUMBER] = str(discnumber)
        if artist != None and len(artist) > 0:
            id3Audio[ID3_ARTIST] = artist
        if bpm != None and bpm > 0:
            id3Audio[ID3_BPM] = str(bpm)
        id3Audio.save()
    except:
        Logger.info("Error during writing easy ID3 tags")
        Logger.info(traceback.format_exc())    
        
def __writeID3(url, audio):
    """Writes the not easy ID3 tags, like 'url', of the given audio to the file at the given url.
    
    Args:
        url: The url of the audio file.
        audio: An Audio object representing the audio file.
    """
    try:
        Logger.info(" -> writeID3 for audio ")
        media = audio.getMedia()
        if media!=None:
            usersettings = XMLController.readAllSettings().getCurrentUserSettings()
            username = usersettings.getUsername()
            myRating = media.getRatingForUsername(username)
            if myRating !=None:
                comment = myRating.getComment()
                if comment==None:
                    comment = ""
                id3Audio = id3.ID3(url)
                if comment != None and len(comment) > 0:
                    id3Audio.add(id3.COMM(encoding=3, desc='ID3v1 Comment', lang='eng', text=comment))
                id3Audio.save() 
            else:
                Logger.info("My Rating None in writing ID3 tags")
        else:
            Logger.info("Media none in writing ID3 tags")
    except:
        Logger.info("Error during writing ID3 tags")
        Logger.info(traceback.format_exc()) 
        
def __writeASFTags(url, audio):
    """Writes the ASF tags of the given audio to the file at the given url.
    
    Args:
        url: The url of the audio file.
        audio: An Audio object representing the audio file.
    """
    try:
        asfAudio = ASF(url)
        #collect information
        title = audio.getMedia().getTitle()
        year = audio.getMedia().getYear()
        composer = audio.getMedia().getComposer()
        tracknumber = audio.getTracknumber()
        album = None
        if audio.getMedia().getCollection() != None:
            album = audio.getMedia().getCollection().getName()
        length = audio.getMedia().getLength()
        genre = None
        if audio.getMedia().getGenre() != None:
            genre = audio.getMedia().getGenre().getName()
#        discnumber = audio.getDiscnumber()
        artist = audio.getArtist().getName()
#        bpm = audio.getBPM()
        lyrics = audio.getLyrics()

        
        #write information to file
        if title != None and len(title) > 0:
            asfAudio[ASF_TITLE] = title
        if year != None and len(year) > 0:
            asfAudio[ASF_YEAR] = year
        if composer != None and len(composer) > 0:
            asfAudio[ASF_COMPOSER] = composer
        if tracknumber != None and tracknumber > 0:
            asfAudio[ASF_TRACKNUMBER] = str(tracknumber)
        if album != None and len(album) > 0:
            asfAudio[ASF_ALBUM] = album
        if length != None and length > 0:
            asfAudio[ASF_LENGTH] = str(length)
        if genre != None and len(genre) > 0:
            asfAudio[ASF_GENRE] = genre
#        if discnumber != None and discnumber > 0:
#            asfAudio[ASF_DISCNUMBER] = str(discnumber)
        if artist != None and len(artist) > 0:
            asfAudio[ASF_ARTIST] = artist
#        if bpm != None and bpm > 0:
#            asfAudio[ASF_BPM] = str(bpm)
        if lyrics != None and len(lyrics) > 0:
            asfAudio[ASF_LYRICS] = lyrics
        asfAudio.save()
    except:
        Logger.info("Error during writing asf tags")
        Logger.info(traceback.format_exc())   

def __printID3Tags(url):
    """Prints the ID3 tags to stdout of the audio file at the given url.
    
    Args:
        url: The url of the audio file.
    """
    try:
        audio = MP3(url)
        print audio.pprint()
    except:
        Logger.info("Error during printing ID3 tags")
        Logger.info(traceback.format_exc())

def __printASFTags(url):
    """Prints the ASF tags to stdout of the audio file at the given url.
    
    Args:
        url: The url of the audio file.
    """
    try:
        audio = ASF(url)
        for item in audio.items():
            print item
#        print audio.pprint()
        print "print asf tags not implemented yet"
    except:
        Logger.info("Error during printing asf tags")
        Logger.info(traceback.format_exc())
